package com.hhd.pdf.components.table;

import com.hhd.pdf.components.AbstractPdfComponent;
import com.hhd.pdf.components.table.factory.TableFooterFactory;
import com.hhd.pdf.components.table.factory.TableHeaderFactory;
import com.hhd.pdf.context.GeneratorContext;
import com.hhd.pdf.utils.PdfUtils;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfDiv;
import com.itextpdf.text.pdf.PdfPTable;
import com.hhd.pdf.components.table.factory.TableBodyFactory;
import com.hhd.pdf.CommonUtils;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

@Component
public class TableComponentV2 extends AbstractPdfComponent {

    @Override
    public void parseComponent(Element element, GeneratorContext context) throws Exception {
        TableVo tableVo = getTableParsed(element);
        PdfPTable pdfPTable = createTable(tableVo, element, context, tableVo);
        TableBorderHelper tableBorderHelper = new TableBorderHelper();

        buildTable(context, pdfPTable, tableVo, tableBorderHelper, element);
    }

    private void buildTable(GeneratorContext context, PdfPTable pdfPTable, TableVo tableVo, TableBorderHelper tableBorderHelper, Element element) throws DocumentException, IOException {
        drawHeader(pdfPTable, context, tableVo, tableBorderHelper);

        drawBody(pdfPTable, context, tableVo, tableBorderHelper);

        drawFooter(pdfPTable, context, tableVo, tableBorderHelper);

        addTableToDocument(context, pdfPTable, element);
    }

    private void drawBody(PdfPTable pdfPTable, GeneratorContext context, TableVo tableVo, TableBorderHelper tableBorderHelper) throws DocumentException, IOException {
        TableBodyFactory.bodyBuilder()
                .tableVo(tableVo)
                .context(context)
                .pdfPTable(pdfPTable)
                .tableBorderHelper(tableBorderHelper)
                .build()
                .create();
    }

    private void drawFooter(PdfPTable pdfPTable, GeneratorContext context, TableVo tableVo, TableBorderHelper tableBorderHelper) throws DocumentException, IOException {
        TableFooterFactory.footBuilder()
                .tableVo(tableVo)
                .context(context)
                .pdfPTable(pdfPTable)
                .tableBorderHelper(tableBorderHelper)
                .build()
                .create();
    }

    private void addTableToDocument(GeneratorContext context, PdfPTable pdfPTable, Element element) throws DocumentException {
        PdfDiv pdfDiv = PdfUtils.wrapDiv(pdfPTable, getPaddingTop(element), 30, 10, 30);
        context.getDocument().add(pdfDiv);
    }

    private static int getPaddingTop(Element element) {
        try {
            Attribute paddingTop = element.attribute("paddingTop");
            return Integer.parseInt(paddingTop.getText());
        } catch (Exception e) {
        }
        return 15;
    }


    private void drawHeader(PdfPTable pdfPTable,
                            GeneratorContext context,
                            TableVo tableVo,
                            TableBorderHelper tableBorderHelper) throws DocumentException, IOException {
        TableHeaderFactory.headBuilder()
                .tableVo(tableVo)
                .context(context)
                .pdfPTable(pdfPTable)
                .tableBorderHelper(tableBorderHelper)
                .build()
                .create();
    }

    private PdfPTable createTable(TableVo tableVo, Element element,
                                  GeneratorContext context,
                                  TableVo tableVo1) {
        return createTable(tableVo, element, context, tableVo.getTrs());
    }

    private PdfPTable createTable(TableVo table,
                                  Element element,
                                  GeneratorContext context,
                                  List<TrVo> trs) {
        TrVo trVo = trs.get(0);
        List<TdVo> tds = trVo.getTds();
        int colNum = 0;
        colNum = getColNum(tds, colNum);
        return PdfUtils.createTable(colNum, context.getGeneratorParameters().getInitPageWidth());
    }

    private static int getColNum(List<TdVo> tds, int colNum) {
        for (TdVo td : tds) {
            Attribute colSpan = td.getTd().attribute("colSpan");
            if (!CommonUtils.isEmpty(colSpan)) {
                String value = colSpan.getValue();
                colNum += Integer.parseInt(value);
            } else {
                colNum++;
            }
        }
        return colNum;
    }

    private static TableVo getTableParsed(Element element) {
        TableXmlParser tableXmlParser = new TableXmlParser(element);
        return tableXmlParser.getTable();
    }

    @Override
    public String getName() {
        return "table";
    }
}
